<?php

/**
 * Dumps the contents of a module resource.
 *
 * @author    Mon Zafra <monzee at gmail>
 * @copyright (c)2009 Mon Zafra
 * @category  Mz
 * @package   Mz_Module
 * @license   http://mz-project.googlecode.com/svn/trunk/LICENSE     MIT License
 * @version   SVN: $Id: IndexController.php 3 2009-02-18 18:55:27Z monzee $
 * @todo Test for the possibility of getting a file outside of the public
 *       resource folder by using relative paths in the url
 */
class Resource_IndexController extends Zend_Controller_Action
{
    const DATE_FORMAT = 'D, d M Y H:i:s \G\M\T';
    const MAX_AGE = 2592000; // 30 days in seconds
    protected $_types = array(
        'css' => 'text/css',
        'bmp' => 'image/bmp',
        'gif' => 'image/gif',
        'jpg' => 'image/jpeg',
        'jpeg'=> 'image/jpeg',
        'png' => 'image/png',
        'js'  => 'text/javascript',
        'html'=> 'text/html',
        'htm' => 'text/html',
        'txt' => 'text/plain',
    );

    public function __call($method, $args)
    {
        $req = $this->_request;
        $res = $this->_response;

        /* @var $req Zend_Controller_Request_Http */
        $path = $req->getPathInfo();
        $module = $req->getParam('resourceModule');
        $req->setParam('resourceModule', null); // unset param

        // TODO: this would fail if the base url contains the name of this module
        $resource = substr($path, strpos($path, $module) + strlen($module) + 1);

        $targetModule = substr($resource, 0, strpos($resource, '/'));
        $resource = substr($resource, strlen($targetModule) + 1);
        $file = $this->_helper->module($targetModule)->pathTo('public/' . $resource);
        $ext = pathinfo($file, PATHINFO_EXTENSION);

        // this has to be here because the target module might enable the layout
        $this->_helper->viewRenderer->setNoRender(true);
        if (Zend_Controller_Action_HelperBroker::hasHelper('Layout')) {
            $this->_helper->layout->disableLayout();
        }

        $res->setHeader('Content-Type', $this->_getType($ext));
        if (file_exists($file)) {
            $modTime = filemtime($file);
            $age = self::MAX_AGE;
            $res->setHeader('Cache-Control', 'public, max-age=' . $age, true)
                ->setHeader('Last-Modified', gmdate(self::DATE_FORMAT, $modTime), true)
                ->setHeader('Expires', gmdate(self::DATE_FORMAT, time() + $age), true)
                ->setHeader('Pragma', null, true);

            $lastMod = $req->getHeader('If-Modified-Since');
            if (!empty($lastMod) && $modTime <= strtotime($lastMod)) {
                $res->setHttpResponseCode(304); // Not modified
                return;
            }

            readfile($file); // read and output directly
        } else {
            $res->setHttpResponseCode(404); // Not found
        }
    }

    protected function _getType($ext, $default = 'text/plain')
    {
        return isset($this->_types[$ext]) ? $this->_types[$ext] : $default;
    }

}
